package com.cup.plat.aspect;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;


/**
 * controller 切面
 * 解析参数
 * @author alan.zhao
 */
@Component
@Aspect
public class ControllerAspect {
	
	private Logger logger = LoggerFactory.getLogger(ControllerAspect.class);
	
	@Autowired(required = false)
	private HttpServletRequest request;
	
	@Pointcut("execution(public * com.cup.plat..*.web.*.*(..))")
	private void webPointcut() {}

    private long respTimeLimit;

    ThreadLocal<Long> startTime = new ThreadLocal<>();

	public long getRespTimeLimit() {
		return respTimeLimit;
	}

	public void setRespTimeLimit(long respTimeLimit) {
		this.respTimeLimit = respTimeLimit;
	}

	@Before("webPointcut()")
	public void doBefore(JoinPoint joinPoint){
		startTime.set(System.currentTimeMillis());
		
		String queryString = "";
		
		if(RequestMethod.GET.name().equals(request.getMethod()) 
				|| RequestMethod.DELETE.name().equals(request.getMethod())){
			
			// get 形式参数获取
			Enumeration<String> pNames=request.getParameterNames(); 
			while(pNames.hasMoreElements()){ 
				
				String name = pNames.nextElement(); 
				String value = request.getParameter(name); 
				queryString += name + "=" + value + "&";
			} 
		}else{
			// post put解析参数
			Object[] params = joinPoint.getArgs();
			
			for(Object p : params){
				queryString += " params：" + p.toString();
			}
		}
		
		logger.info("{}@[{}]@[{}]@[{}]",
				startTime.get(),
				request.getRequestURL().toString(), 
				request.getMethod(), 
				queryString);
	}
	
	@AfterReturning(pointcut="webPointcut()", argNames="ret", returning="ret")
	public void doAfterReturning(JoinPoint joinPoint, Object ret) throws Throwable {
		
        logger.info("{}@[{}]@[{}] cost [{}] ms.",
        		startTime.get(),
        		joinPoint.getSignature().getDeclaringTypeName(), 
        		joinPoint.getSignature().getName(), 
        		(System.currentTimeMillis() - startTime.get()));
    }
}